#pragma once

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cerrno>
#include <unistd.h>
#include <cstdio>     
#include <cstdlib>
#include "log.hpp"
#include <sys/ipc.h>
#include <cstring>
#include <sys/shm.h>

using namespace std;

Log log;

// 共享内存的大小一般建议是4096的整数倍
// 4097,实际上操作系统给你的是4096*2的大小


const int sz= 4096; 
const string pathname="/home/ubuntu/lesson1/part1/4.sharedMem";      //这是一个指向现有文件的路径名的指针。这个文件必须是一个实际存在的文件，并且调用者需要有访问该文件的权限。
const int proj_id = 0x6666;     //proj_id 应该在 0 到 255 的范围内，因为它会被转换为一个 8 位的值。 
//这个参数的作用是允许同一个系统上的不同项目或应用程序使用同一个文件生成不同的键值。例如，不同的应用程序可以使用同一个 /etc/passwd 文件，但通过指定不同的 proj_id 来生成不同的键值。


key_t GetKey()
{
    key_t k = ftok(pathname.c_str(), proj_id);
    if (k == -1)
    {
        log(Fatal, "ftok error : %s", strerror(errno));
        exit(1);
    }

    log(Info,"ftok success, key is : 0x%x", k);
    return k;
}

int GetSharedMemory(int flag)
{
    key_t key = GetKey();
    int shmid = shmget(key, sz, flag);
    if (shmid == -1)
    {
        log(Fatal, "shmget error : %s", strerror(errno));
        exit(2);
    }

    log(Info, "create share memory success, shmid: %d", shmid);

    return shmid;
}

int CreateShm()
{
    return GetSharedMemory(IPC_CREAT | IPC_EXCL | 0666);
}


int GetShm()
{
    return GetSharedMemory(IPC_CREAT);
}



#define FIFO_FILE "./myfifo"
#define MODE 0666

enum
{
    FIFO_CREATE_ERR = 1,        //用逗号分隔成员
    FIFO_DELETE_ERR,
    FIFO_OPEN_ERR
};  //自定义类型结尾需要分号；

class Init
{
public:
    Init()    //构造函数创建管道
    {
        int ret = mkfifo(FIFO_FILE, MODE);
        if (ret < 0)
        {
            perror("mkfifo");
            exit(FIFO_CREATE_ERR);
        }
    }


    ~Init()   //析构函数删除管道
    {
        int ret = unlink(FIFO_FILE);
        if (ret == -1)
        {
            perror("unlink");
            exit(FIFO_DELETE_ERR);
        }
    }

};   //class与struct结尾需要分号；
